<template>
  <svg id="show-data">
    <template v-for="(item, index) in vitalLineOut" :key="index">
      <line
        v-if="item.type === 'line'"
        :x1="getPixel(item.x1)"
        :y1="getPixel(item.y1)"
        :x2="getPixel(item.x2)"
        :y2="getPixel(item.y2)"
      :stroke="item.style.stroke"
      :stroke-width="item.style.strokeWidth"
      :stroke-dasharray="item.style.strokeDasharray"
      />
      <SymbolSvg v-if="item.type === 'symbol'" :config="item" :showSize="config.showSize" />
    </template>
  </svg>
</template>

<script setup lang="ts">
import {
  reactive,
  ref,
  onMounted,
  computed,
  watch,
  getCurrentInstance,
} from "vue";

import SymbolSvg from "../common/SymbolSvg.vue";
import Custom_Variable from "../CUSTOM";

import moment from "moment";

const props = defineProps({
  config: Object,
});

let vitalLineOut = ref([]);


let getPixel = (value) => { 
    // console.log("getPixel",value,props.config);
    
    return value * props.config.scale + props.config.unit
};

// 定义格式化日期的函数
function formatDate(date: Date): string {
  const year = date.getFullYear();
  // 月份从 0 开始计数，所以要加 1，同时补零
  const month = String(date.getMonth() + 1).padStart(2, '0'); 
  const day = String(date.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}


/**
 * @method 解析绘制折线线条数据(脉搏、心率、体温等)
 * @param {Object} props
 * @returns {Array}
 * 对体温做特殊处理，(合并腋温/肛温/口温/耳温/额温/体温等）
 * 对脉搏心率做特殊处理， 合并(脉搏/心率， 暂不处理)
 * 脉搏或心率和体温重叠，体温的图标放大【功能 #3276
 */
let parseVitalLineOut = () => {
  let { config, data, items, scale, unit, split, ...otherProps } = props.config;

  items = props.config.showData.items;

  let vitalLineOutToConfig = config["vitalLineOutToConfig"];
  let linePenIdToStyle = config["linePenIdToStyle"];
  let symbolIdToStyle = config["symbolIdToStyle"];
  let vitalShowToConfig = config["vitalShowToConfig"] || {};
  let vitalLineOutSvg = [];
  let keyToVitalLineOut = {};

  items = items || [];
  /**
   * 呼吸机
   */
  let ventilatorData = [];
  items.forEach((item) => ventilatorData.push(item["_attr"] || {}));
  ventilatorData =
    ventilatorData.filter((f) => f.vitalsigns.includes("呼吸机")) || [];
  // 获取符合绘制线条的数据，根据name分类
  for (let i = 0; i < items.length; i++) {
    let attr = items[i]["_attr"];
    let { vitalsigns, vitalsignsvalues, cellindex, disScale, ...other } = attr;
    let showVitalSigns = findMatchName(vitalLineOutToConfig, vitalsigns);
    // vitalsignsvalues可能为undefined
    if (vitalLineOutToConfig[showVitalSigns]) {
      /** 核实功能 */
      let value = vitalsignsvalues && vitalsignsvalues.split("V")[0];

      if (!keyToVitalLineOut[showVitalSigns]) {
        keyToVitalLineOut[showVitalSigns] = [];
      }
      let nameShowConfig = vitalShowToConfig[showVitalSigns] || {};
      if (disScale !== undefined && nameShowConfig.columnsInDay) {
        cellindex = disScale * (7 * nameShowConfig.columnsInDay);
      }
      keyToVitalLineOut[showVitalSigns].push({
        ...other,
        name: vitalsigns,
        config: vitalLineOutToConfig[showVitalSigns],
        data: attr,
        value,
        cellIndex: cellindex,
      });
    }
  }
  let isMX = ["心率", "脉搏"];
  // 按从小到大排序
  // 如果是脉搏和心率， cellIndex相等时， 心率排在前面
  // 脉搏用红圆点标识，心率用红圈标识，同时录入，值不同，先连心率后连脉搏。
  for (let name in keyToVitalLineOut) {
    let list = keyToVitalLineOut[name];
    list = list.sort((a, b) => {
      if (
        isMX.indexOf(a.name) > -1 &&
        isMX.indexOf(b.name) &&
        a.cellIndex === b.cellIndex
      ) {
        if (a.name === "脉搏" && b.name === "心率") {
          return -1;
        } else {
          return 0;
        }
      } else {
        return a.cellIndex - b.cellIndex;
      }
    });
    keyToVitalLineOut[name] = list;
  }

  // 体温，脉搏，心率，疼痛评分等绘制线条时排序
  let nameToSortNo = { 疼痛评分: 1, 脉搏: 2, 心率: 3, 体温: 4 };
  let vitalLineOutArray = [];
  for (let name in keyToVitalLineOut) {
    vitalLineOutArray.push({
      name: name,
      sortNo: nameToSortNo[name],
      pointData: keyToVitalLineOut[name],
    });
  }
  vitalLineOutArray.sort((a, b) => a.sortNo - b.sortNo);
  let xlData =
    (vitalLineOutArray.filter((f) => f.name === "心率")[0] || {}).pointData ||
    [];
  // 绘制线条
  for (let k = 0; k < vitalLineOutArray.length; k++) {
    let { name, pointData } = vitalLineOutArray[k];
    let nextName = (vitalLineOutArray[k + 1] || {}).name;
    let onName = (vitalLineOutArray[k - 1] || {}).name;
    let config = vitalLineOutToConfig[name];
    // console.log(config, 'config');
    // svg中的path不识别标记单位， 所以用line连接折线，不使用path
    // console.log({pointData, vitalLineOutArray}, 'pointData');
    for (let i = 0; i < pointData.length; i++) {
      let point = pointData[i];
      let { data, name, value, ...other } = point;
      let nextPoint = pointData[i + 1];
      let baseValue = config["base-value"]; // 初始值
      let curScale = config["scale"]; // 每个小格所占刻度
      let symbolId = config["symbol"]; // 符号id
      let brokenLine = config["broken-line"]; // 脉搏心率是否断线
      let overLapping = config["over-lapping"]; // 体温脉搏心率重合类型,
      let penId = config["pen-id"];
      let dayTime = config["day-time"]; // 脉搏心率上下连线 1 同天同时间连线
      let penStyle = linePenIdToStyle[penId] || {};
      let styleColor = penStyle["color"];
      let styleWidth = penStyle["pen-width"];
      let penSolid = penStyle["pen-style"];
      let disConfigCx = !split ? config.cx / 2 : 0;
      let showValue = value;
      let isShowMaxPoint = true;
      let isShowMinPoint = true;
      let existMax = false;
      let existMin = false;
      let specialSymbol;
      // columnsInDay: 1
      // lineCount: 2
      // name: "皮试"
      // newLine: 1
      // spaceMark: "/"
      // splitType: "undefined"
      // 存在多个name时， 取得当前name的symbol序号
      let includeName = config["include-name"];
      if (includeName) {
        let includeNameArray = includeName.split(",");
        let index = includeNameArray.indexOf(name);
        specialSymbol = config[`symbol${index}`];
        // 体温特殊处理 发热
        if (
          !!config[`pen-id${index}`] &&
          name === "发热" &&
          onName !== ["不升", "发热"]
        ) {
          penId = config[`pen-id${index}`];
          penStyle = linePenIdToStyle[penId] || {};
          styleColor = penStyle["color"];
          styleWidth = penStyle["pen-width"];
          penSolid = penStyle["pen-style"];

          let len = vitalLineOutSvg.filter((f) => f.type === "line").length;
          if (!!len) {
            vitalLineOutSvg.filter((f) => f.type === "line")[len - 1].style = {
              stroke: styleColor ? `rgba(${styleColor})` : "rgba(0,0,0,1)",
              strokeWidth: styleWidth,
              strokeDasharray: penSolid === 2 ? "3,3" : undefined,
            };
            if (
              !vitalLineOutSvg.filter((f) => f.type === "line")[len - 1]
                .isOffsetX
            ) {
              vitalLineOutSvg.filter((f) => f.type === "line")[
                len - 1
              ].isOffsetX = true;
              // console.log(vitalLineOutSvg.filter(f => f.type === 'line')[len - 1], '1');
              vitalLineOutSvg.filter((f) => f.type === "line")[len - 1].x2 =
                vitalLineOutSvg.filter((f) => f.type === "line")[len - 1].x2 +
                1.5;
            }
          }
        }
      }

      const pacemakerArray =
        config["pacemaker"] && config["pacemaker"].split
          ? config["pacemaker"].split(",")
          : [];
      const includeNameArray = includeName ? includeName.split(",") : [];

      // 起搏器特殊处理
      if (
        ["心率", "脉搏"].includes(name) &&
        point.flag == 1 &&
        config["pacemaker"]
      ) {
        if (includeName) {
          specialSymbol =
            pacemakerArray[includeNameArray.findIndex((v) => v === name)] ||
            config["pacemaker"];
        } else {
          specialSymbol = pacemakerArray[0] || config["pacemaker"];
        }
      }

      // 特殊处理的部分
      let maxValue = config["max-value"]; // 最大值
      let showMaxValue = config["show-max-value"]; // 超过最大值显示位置
      let maxPoint = config["max-point"]; //  超过最大值时是否画符号
      maxPoint = maxPoint === undefined ? true : maxPoint;
      let minValue = config["min-value"]; // 最小值
      let showMinValue = config["show-min-value"]; // 低于最小值显示位置
      let minPoint = config["min-point"]; // 低于最小值时是否画符号
      minPoint = minPoint === undefined ? true : minPoint;
      let maxSymbolId = config["max-symbol"]; // 大于最大值时显示向上的箭头
      let minSymbolId = config["min-symbol"]; // 小于最小值时显示向下的箭头

      let maxSymbolColor = config["max-symbol-color"]; // 高温图标颜色
      let minSymbolColor = config["min-symbol-color"]; // 低温图标颜色

      //console.log({config, maxValue, showMaxValue, maxPoint });

      if (maxValue && value > maxValue) {
        existMax = true;
        showValue = showMaxValue;
        isShowMaxPoint = maxPoint;
      } else if (minValue && value < minValue) {
        existMin = true;
        showValue = showMinValue;
        isShowMinPoint = minPoint;
      }
      let x1 =
        config.x +
        disConfigCx +
        config.cx * point.cellIndex +
        (name === "发热" ? 2 : 0);
      let y1 = config.y - ((showValue - baseValue) / curScale) * config.cy;

      let x2 = x1;
      let y2 = y1;

      /**
       * 体温特殊处理
       * 发热 跟下一个体温不连线
       * 不升 拒测 外出 跟前后不连线
       * 晋江 呼吸 mr跟下一个图形不连线
       */
      let mrFlag = false;
      // if(name === '呼吸') {
      //   let date = point.date && moment(point.date).add(1, 'day').format('YYYY-MM-DD')
      //   let nextDate = nextPoint && nextPoint.date && moment(nextPoint.date).format('YYYY-MM-DD')
      //   mrFlag = name === '呼吸' && !(date === nextDate) && Custom_Variable.isBreath
      // }
      if (name.includes("呼吸")) {
        // let date = point.date && moment(point.date).format("YYYY-MM-DD");
        let date = point.date && formatDate(point.date);
        let nextDate =
          nextPoint &&
          nextPoint.date &&
        //   moment(nextPoint.date).format("YYYY-MM-DD");
        formatDate(nextPoint.date);
        let days =
          (nextDate && moment(nextDate).diff(moment(date), "days")) || 0;
        const dates = [];
        // days大于0 - 1 等于1 不用做判断
        if (days > 0) days--;
        while (days > 0) {
          dates.push(moment(date).add(days, "day").format("YYYY-MM-DD"));

            console.log("moment",date,days,moment(date).add(days, "day").format("YYYY-MM-DD"));
            

          days--;
        }
        let len = ventilatorData.filter((f) => {
        //   let d = moment(f.date).format("YYYY-MM-DD");
          let d = formatDate(f.date);
          if (dates.includes(d)) return f;
        }).length;
        mrFlag = !!len && Custom_Variable.isBreath;
        // console.log(date, dates, nextDate, 'nextPoint', len, days, mrFlag);
      }
      let breakLineCondition = Custom_Variable.isBreakLine
        ? ["拒测", "外出"]
        : ["不升", "拒测", "外出"];
      if (
        nextPoint &&
        value &&
        nextPoint.value &&
        (brokenLine != "1" ||
          (brokenLine == "1" && point.name == nextPoint.name)) &&
        !breakLineCondition.includes(name) &&
        !breakLineCondition.includes(nextName) &&
        !mrFlag
      ) {
        let newPointValue = nextPoint.value;
        let showNextPointValue = newPointValue;
        if (maxValue && newPointValue > maxValue) {
          showNextPointValue = showMaxValue;
        } else if (minValue && newPointValue < minValue) {
          showNextPointValue = showMinValue;
        }
        x2 = config.x + disConfigCx + config.cx * nextPoint.cellIndex;
        y2 =
          config.y - ((showNextPointValue - baseValue) / curScale) * config.cy;
        vitalLineOutSvg.push({
          type: "line",
          x1,
          y1,
          x2,
          y2,
          style: {
            stroke: styleColor ? `rgba(${styleColor})` : "rgba(0,0,0,1)",
            strokeWidth: styleWidth,
            strokeDasharray: penSolid === 2 ? "3,3" : undefined,
          },
          vitalsigns: name,
          config: config,
        });
      }

      // 体温单 脉搏心率 上线连线 特殊处理
      if (name === "脉搏" && dayTime === 1 && xlData.length > 0) {
        const pulseHeartRate = pulseHeartRate(xlData, point["date"]);
        const xlObj = pulseHeartRate.xlObj;
        xlData = pulseHeartRate.xlData;
        if (Object.keys(xlObj).length !== 0) {
          let newPointValue = xlObj.value;
          let showNextPointValue = newPointValue;
          if (maxValue && newPointValue > maxValue) {
            showNextPointValue = showMaxValue;
          } else if (minValue && newPointValue < minValue) {
            showNextPointValue = showMinValue;
          }
          x2 = config.x + disConfigCx + config.cx * xlObj.cellIndex;
          y2 =
            config.y -
            ((showNextPointValue - baseValue) / curScale) * config.cy;
          vitalLineOutSvg.push({
            type: "line",
            x1,
            y1,
            x2,
            y2,
            style: {
              stroke: styleColor ? `rgba(${styleColor})` : "rgba(0,0,0,1)",
              strokeWidth: styleWidth,
              strokeDasharray: penSolid === 2 ? "3,3" : undefined,
            },
            vitalsigns: name,
            config: config,
          });
        }
      }

      // 如果存在特殊符号，则使用对应的特殊符号
      let curSymbolId = specialSymbol ? specialSymbol : symbolId;

      // 绘制符号
      let symbolStyle = symbolIdToStyle[curSymbolId] || {};
      /**
       * 呼吸机 R展示在呼吸旁边
       */
      let ventilatorFlag = true;
      // if(name === '呼吸机') {
      //   let ventilatorData = items.filter(f => f['_attr']['date'] === point.date && ['呼吸UP','呼吸DOWN', '呼吸'].includes(f['_attr']['vitalsigns']))[0]
      //   point.value = ventilatorData['_attr']['vitalsignsvalues'] || 0
      //   ventilatorFlag = ventilatorData['_attr']['vitalsigns']
      // }
      // console.log(ventilatorData, 'ventilatorData');
      if (
        point.value &&
        ((existMin && isShowMinPoint) ||
          (existMax && isShowMaxPoint) ||
          (!existMin && !existMax))
        // && ventilatorFlag
      ) {
        /**
         * 常州呼吸 呼吸机同时存在时 蓝圈变Ⓡ
         */
        let sym = {};
        let flag =
          !!(ventilatorData || []).filter((f) => f["date"] === point["date"])
            .length && point.name.includes("呼吸");
        vitalLineOutSvg.push({
          ...symbolStyle,
          ...data,
          ...other,
          ...otherProps,
          type: "symbol",
          vitalsignsvalues: point.value,
          unit,
          scale,
          x1,
          y1,
          config,
          name,
          overLapping,
          ...sym,
        });
        if (data.vitalsignsvalues.includes("V")) {
          // 核实
          vitalLineOutSvg.push({
            ...symbolStyle,
            ...data,
            ...other,
            ...otherProps,
            type: "symbol",
            //vitalsignsvalues: point.value,
            vitalsignsvalues: "",
            symbol1: "V",
            unit,
            scale,
            x1,
            y1: y1 - 2.5,
            config,
            name: "",
            overLapping,
            isClick: true,
            ...sym,
          });
        }
        /**
         * 呼吸机 R展示在呼吸旁边
         */
        if (flag)
          vitalLineOutSvg.push({
            ...symbolStyle,
            ...data,
            ...other,
            ...otherProps,
            type: "symbol",
            vitalsignsvalues: point.value,
            unit,
            scale,
            x1: x1 + 3,
            y1,
            name,
            overLapping,
            symbol1: "R",
            vitalsigns: "呼吸机",
            name: "呼吸机",
            isClick: true,
            config: { ...config, "include-name": "呼吸机", name: "呼吸机" },
          });
      }
      // 存在最大值且需要显示向下箭头的
      if (point.value && existMax && maxSymbolId) {
        const maxSymbolStyle = symbolIdToStyle[maxSymbolId];
        if (maxSymbolStyle && maxSymbolColor) {
          maxSymbolStyle.color = maxSymbolColor;
        }
        let distanceT = maxSymbolId == "↑" ? -2 : maxSymbolId == "↓" ? 2 : -2;
        vitalLineOutSvg.push({
          ...maxSymbolStyle,
          ...data,
          ...other,
          ...otherProps,
          type: "symbol",
          vitalsignsvalues: point.value,
          unit,
          scale,
          x1,
          y1: y1 + distanceT,
          config,
          name,
          overLapping,
        });
      }
      // 存在最小值且需要显示向下箭头的
      if (point.value && existMin && minSymbolId) {
        const minSymbolStyle = symbolIdToStyle[minSymbolId];
        if (minSymbolStyle && minSymbolColor) {
          minSymbolStyle.color = minSymbolColor;
        }
        let distanceB = minSymbolId == "↑" ? -2 : minSymbolId == "↓" ? 2 : 2;
        vitalLineOutSvg.push({
          ...minSymbolStyle,
          ...data,
          ...other,
          ...otherProps,
          type: "symbol",
          vitalsignsvalues: point.value,
          unit,
          scale,
          x1,
          y1: y1 + distanceB,
          config,
          name,
          overLapping,
        });
      }
    }
  }

  let resultPoints = findOverlappingPoints(vitalLineOutSvg);
  resultPoints = findOverlappingPointsAll(resultPoints);

  // console.log({ resultPoints, resultPoints1: resultPoints.filter(v=>v.nameJoinSymbol == '脉搏,呼吸') }, 'vitalLineOutSvg');

  return resultPoints;
};

let findMatchName = (vitalLineOutToConfig, vitalsigns) => {
  let returnName = vitalsigns;
  for (let name in vitalLineOutToConfig) {
    let includeName = vitalLineOutToConfig[name]["include-name"] || "";
    if (includeName.indexOf(vitalsigns) > -1) {
      returnName = name;
      break;
    }
  }

  return returnName;
};

/**
 * 查找与脉搏/心率重合的体温点，并将体温图标放大
 * 天台需求，需要在体温单外面加个红圈，体温图标不放大
 * 2020年3月31日21:56:33刘伶俐， 根据体温单xml配置取重叠规则
 * 如果重叠显示，鼠标放上去显示所有的值
 */
let findOverlappingPoints = (vitalLineOutSvg) => {
  let { vitalLineOverlapToConfig, symbolIdToStyle } = props.config.config;
  let vitalLineOutSvgSymbol = vitalLineOutSvg.filter(
    (item) => item.type === "symbol"
  );
  // 获取重合点规则改变
  // 所有体温点
  const allTW = vitalLineOutSvgSymbol.filter(
    (item) => item.config.name === "体温"
  );
  // 所有脉搏点
  const allMB = vitalLineOutSvgSymbol.filter(
    (item) => item.vitalsigns === "脉搏"
  );
  // 所有心率点
  const allXL = vitalLineOutSvgSymbol.filter(
    (item) => item.vitalsigns === "心率"
  );

  // 同类别混合重叠的咋整？TODO
  // 重叠的体温合并显示
  const sameTW = findSamePointMerge(allTW);
  // 重叠的脉搏合并显示
  const sameMB = findSamePointMerge(allMB);
  // 重叠的心率合并显示
  const sameXL = findSamePointMerge(allXL);

  // 获取所有重叠的体温/脉搏/心率点
  let sameTPH = findAllSamePoint([sameTW, sameMB, sameXL]);

  // 获取所有重叠的心率/脉搏点, 过滤掉sameTPH中存在的
  let samePH = findAllSamePoint([sameXL, sameMB], sameTPH);

  // 获取所有重叠的体温/心率点,过滤掉sameTPH中存在的
  let sameTH = findAllSamePoint([sameTW, sameXL], sameTPH);

  // 获取所有重叠的体温/脉搏点,过滤掉sameTPH中存在的
  let sameTP = findAllSamePoint([sameTW, sameMB], sameTPH);

  // 处理折线中的重叠,如果有通过误差重叠图标的会导致折线坐标显示不对
  const samePoints = samePH.concat(sameTH).concat(sameTP).concat(sameTPH);
  // 过滤掉体温脉搏心率重叠的symbol
  let newVitalLineOutSvg = vitalLineOutSvg.filter((item) => {
    return (
      item.type === "line" ||
      samePoints.filter(
        (point) =>
          point.config.name === item.config.name &&
          point.x1 === item.x1 &&
          point.y1 === item.y1
      ).length === 0
    );
  });
  for (let i = 0; i < samePoints.length; i++) {
    let newPoint = samePoints[i];
    // 存在误差重叠
    if ("oldX1" in newPoint) {
      let lines = newVitalLineOutSvg.filter((item) => item.type === "line");

      let sameLines1 = lines.filter((item) => {
        return item.x1 === newPoint.oldX1 && item.y1 === newPoint.oldY1;
      });
      sameLines1.forEach((item) => {
        item.x1 = newPoint.x1;
        item.y1 = newPoint.y1;
      });
      let sameLines2 = lines.filter((item) => {
        return item.x2 === newPoint.oldX1 && item.y2 === newPoint.oldY1;
      });
      sameLines2.forEach((item) => {
        item.x2 = newPoint.x1;
        item.y2 = newPoint.y1;
      });
    }
  }

  // 重叠配置
  let samePHConfig = vitalLineOverlapToConfig["脉搏,心率"];
  let sameTHConfig = vitalLineOverlapToConfig["体温,心率"];
  let sameTPConfig = vitalLineOverlapToConfig["体温,脉搏"];
  let sameTPHConfig = vitalLineOverlapToConfig["体温,脉搏,心率"];

  let showSamePHPoint = [];
  let showSameTHPoint = [];
  let showSameTPPoint = [];
  let showSameTPHPoint = [];

  // 处理脉搏心率重叠 over-lapping：1单独图标显示 2重叠显示，不做特殊处理3只取脉搏描点，心率不画4只取心率描点，脉搏不画
  if (samePHConfig) {
    let overLapping = ["undefined", 2, "2"].includes(
      samePHConfig["over-lapping"]
    )
      ? 2
      : samePHConfig["over-lapping"];
    if (overLapping == 1) {
      // 单独图标显示
      showSamePHPoint = parseOverLappingSpecial(
        samePH,
        samePHConfig,
        symbolIdToStyle
      );
    }
    if (overLapping == 2) {
      showSamePHPoint = samePH;
    }
    if (overLapping == 3) {
      // 只取脉搏描点
      showSamePHPoint = samePH.filter((item) => item.vitalsigns === "脉搏");
    }
    if (overLapping == 4) {
      // 支取心率描点
      showSamePHPoint = samePH.filter((item) => item.vitalsigns === "心率");
    }
  }
  // 处理体温心率重叠
  // over-lapping：1单独图标显示 2重叠显示，不做特殊处理3体温在上，覆盖脉搏 4脉搏在上，覆盖体温
  if (sameTHConfig) {
    showSameTHPoint = parseOverLapping(sameTH, sameTHConfig, symbolIdToStyle);
  }
  // 处理体温脉搏重叠
  if (sameTPConfig) {
    showSameTPPoint = parseOverLapping(sameTP, sameTPConfig, symbolIdToStyle);
  }
  // 处理体温脉搏心率重叠
  if (sameTPHConfig) {
    showSameTPHPoint = parseOverLapping(
      sameTPH,
      sameTPHConfig,
      symbolIdToStyle
    );
  }

  let newSamePoints = showSamePHPoint
    .concat(showSameTHPoint)
    .concat(showSameTPPoint)
    .concat(showSameTPHPoint);

  newVitalLineOutSvg = newVitalLineOutSvg.concat(newSamePoints);
  return newVitalLineOutSvg;
};

/**
 * 脉搏呼吸重合
 * vitallineoverlap
 */
let findOverlappingPointsAll = (vitalLineOutSvg) => {
  // 试着不特定写死，完全按照配置来
  let { vitalLineOverlapToConfig, symbolIdToStyle } = props.config.config;
  let newVitalLineOutSvg = vitalLineOutSvg;
  let vitalLineOutSvgSymbol = vitalLineOutSvg.filter(
    (item) => item.type === "symbol"
  );

  // 排除之前写死的处理
  let excludes = ["脉搏,心率", "体温,脉搏,心率", "体温,心率", "体温,脉搏"];
  // 需要将类别多的重叠先处理吗， 暂定不处理
  for (let overlapName in vitalLineOverlapToConfig) {
    if (!excludes.includes(overlapName)) {
      let names = overlapName.split(",");
      let samePoints = [];
      names.forEach((name) => {
        let allPoints = vitalLineOutSvgSymbol.filter(
          (item) => item.config.name === name
        );
        let curSamePoints = findSamePointMerge(allPoints);
        samePoints.push(curSamePoints);
      });
      let sameOverlapPoints = findAllSamePoint(samePoints, []);

      newVitalLineOutSvg = newVitalLineOutSvg.filter((item) => {
        return (
          item.type === "line" ||
          sameOverlapPoints.filter(
            (point) =>
              point.config.name === item.config.name &&
              point.x1 === item.x1 &&
              point.y1 === item.y1
          ).length === 0
        );
      });
      for (let i = 0; i < sameOverlapPoints.length; i++) {
        let newPoint = sameOverlapPoints[i];
        // 存在误差重叠
        if ("oldX1" in newPoint) {
          let lines = newVitalLineOutSvg.filter((item) => item.type === "line");

          let sameLines1 = lines.filter((item) => {
            return item.x1 === newPoint.oldX1 && item.y1 === newPoint.oldY1;
          });
          sameLines1.forEach((item) => {
            item.x1 = newPoint.x1;
            item.y1 = newPoint.y1;
          });
          let sameLines2 = lines.filter((item) => {
            return item.x2 === newPoint.oldX1 && item.y2 === newPoint.oldY1;
          });
          sameLines2.forEach((item) => {
            item.x2 = newPoint.x1;
            item.y2 = newPoint.y1;
          });
        }
      }

      let showSamePoint = parseOverLapping(
        sameOverlapPoints,
        vitalLineOverlapToConfig[overlapName],
        symbolIdToStyle
      );

      // console.log('showSamePoint', {  overlapName, sameOverlapPoints, showSamePoint  })

      newVitalLineOutSvg = newVitalLineOutSvg.concat(showSamePoint);
    }
  }
  return newVitalLineOutSvg;
};

/**
 * 同类型的点重合后合并显示
 */
let findSamePointMerge = (points) => {
  let index = 0;
  for (let i = 0; i < points.length; i++) {
    let item = points[i];
    for (let j = 0; j < points.length; j++) {
      let point = points[j];
      let isFirst = item.x1 !== point.x1 || item.y1 !== point.y1;
      let isPointCoincidence = isPointCoincidenceF(item, point);
      if (isFirst && isPointCoincidence) {
        // 重叠
        point.sameIndex = index;
        item.sameIndex = index;
        index++;
      }
    }
  }
  // 先取出没有与之重叠的点
  let showPoints = points.filter((item) => !("sameIndex" in item));

  // 取出sameIndex重复
  let sameIndexTo = {};
  for (let i = 0; i < points.length; i++) {
    if ("sameIndex" in points[i]) {
      if (!sameIndexTo[points[i].sameIndex]) {
        sameIndexTo[points[i].sameIndex] = [];
      }
      sameIndexTo[points[i].sameIndex].push(points[i]);
    }
  }
  for (let sameIndex in sameIndexTo) {
    let values = sameIndexTo[sameIndex];
    showPoints.push({
      ...values[0],
      values: values.length > 1 ? values : undefined,
    });
  }

  return showPoints;
};

/**
 * 判断点重合的误差， 即xy轴坐标差
 */
let isPointCoincidenceF = (a, b) => {
  const { showSize } = a;
  const circle = showSize["printErrorValue"] || 0; // 重合误差小于该值时算重叠

  // 等于0时，则完全相等才算重叠
  if (circle === 0) {
    return a.x1 === b.x1 && a.y1 === b.y1;
  }

  // 圆心的距离
  const between = Math.sqrt(
    Math.pow(a.x1 - b.x1, 2) + Math.pow(a.y1 - b.y1, 2)
  );

  // 如果重合了写入新的点位置
  let newPointX = (a.x1 + b.x1) / 2;
  let newPointY = (a.y1 + b.y1) / 2;

  if (circle > 0 && between <= circle) {
    // 点改变了之后，折线坐标也应该跟着变， 不然线条会奇怪
    // 存放初始坐标
    if (!("oldX1" in a)) {
      a.oldX1 = a.x1;
      a.oldY1 = a.y1;
    }
    if (!("oldX1" in b)) {
      b.oldX1 = b.x1;
      b.oldY1 = b.y1;
    }

    a.x1 = newPointX;
    a.y1 = newPointY;
    b.x1 = newPointX;
    b.y1 = newPointY;
  }
  return between <= circle;
};

/**
 * 查找重合的点
 * 同类别重叠也可
 */
let findAllSamePoint = (pointArray, sameTPH) => {
  let begin = 1;
  let samePointCache = pointArray[0].filter((item) => {
    let allIn = [];
    for (let i = begin; i < pointArray.length; i++) {
      let isIn =
        pointArray[i].filter((point) => {
          return isPointCoincidenceF(item, point);
        }).length > 0;
      if (isIn) {
        allIn.push(true);
      }
    }
    return allIn.length === pointArray.length - 1;
  });

  let samePoint = samePointCache;

  for (let i = 0; i < samePointCache.length; i++) {
    const item = samePointCache[i];
    for (let j = begin; j < pointArray.length; j++) {
      let same = pointArray[j].filter((point) => {
        return isPointCoincidenceF(item, point);
      });
      samePoint = samePoint.concat(same);
    }
  }

  // 将samePoint中 sameTPH中存在的过滤掉
  if (sameTPH) {
    samePoint = samePoint.filter((item) => {
      return (
        sameTPH.findIndex((point) => {
          return (
            item.vitalsigns === point.vitalsigns &&
            isPointCoincidenceF(item, point)
          );
        }) === -1
      );
    });
  }

  // 过滤掉时间点相同的同类别samePoint
  let dateTypeTo = {};
  for (let i = 0; i < samePoint.length; i++) {
    let { name, date } = samePoint[i];
    dateTypeTo[`${name}_${date}`] = samePoint[i];
  }

  //console.log('findAllSamePoint', { pointArray, samePoint, samePointCache });

  return Object.keys(dateTypeTo).map((key) => dateTypeTo[key]);
};

/**
 * 解析单独图标显示
 * lapping-type: 1或者无值时详情重叠合并 2详情分开点击显示
 * @returns {*}
 */
let parseOverLappingSpecial = (samePoint, sameConfig, symbolIdToStyle) => {
  if (samePoint.length === 0) return [];
  let showSamePoint = [];
  let T = ["口温", "腋温", "肛温", "耳温", "额温", "体温", "发热"];
  let overSymbol = sameConfig["over-symbol"];

  let lappingType = sameConfig["lapping-type"] || 1;
  let symbolIdList = (overSymbol ? overSymbol + "" : "").split(",");
  let placerOverSymbol = sameConfig["placer-over-symbol"];
  let placerSymbolIdList = placerOverSymbol
    ? `${placerOverSymbol}`.split(",")
    : symbolIdList;

  let symbolId = symbolIdList[0];
  let symbolStyle = symbolIdToStyle[symbolId];
  let nameToSymbolStyle = {};
  nameToSymbolStyle[sameConfig.name] = symbolStyle;

  if (sameConfig.name === "体温,脉搏,心率") {
    symbolIdList.forEach((symbolId, index) => {
      nameToSymbolStyle[`${T[index]},脉搏,心率`] = symbolIdToStyle[symbolId];
    });
    placerSymbolIdList.forEach((symbolId, index) => {
      nameToSymbolStyle[`${T[index]},起搏器,心率`] = symbolIdToStyle[symbolId];
      nameToSymbolStyle[`${T[index]},脉搏,心脏起搏器`] =
        symbolIdToStyle[symbolId];
      nameToSymbolStyle[`${T[index]},起搏器,心脏起搏器`] =
        symbolIdToStyle[symbolId];
    });
  } else if (sameConfig.name == "体温,脉搏") {
    symbolIdList.forEach((symbolId, index) => {
      nameToSymbolStyle[`${T[index]},脉搏`] = symbolIdToStyle[symbolId];
    });
    placerSymbolIdList.forEach((symbolId, index) => {
      nameToSymbolStyle[`${T[index]},起搏器`] = symbolIdToStyle[symbolId];
    });
  } else if (sameConfig.name == "体温,心率") {
    symbolIdList.forEach((symbolId, index) => {
      nameToSymbolStyle[`${T[index]},心率`] = symbolIdToStyle[symbolId];
    });
    placerSymbolIdList.forEach((symbolId, index) => {
      nameToSymbolStyle[`${T[index]},心脏起搏器`] = symbolIdToStyle[symbolId];
    });
  } else if (sameConfig.name == "脉搏,心率") {
    nameToSymbolStyle["起搏器,心率"] = symbolIdToStyle[placerSymbolIdList[0]];
    nameToSymbolStyle["脉搏,心脏起搏器"] =
      symbolIdToStyle[placerSymbolIdList[0]];
    nameToSymbolStyle["起搏器,心脏起搏器"] =
      symbolIdToStyle[placerSymbolIdList[0]];
  }
  // 一般全局均分显示存在的情况
  // 体温和体温重叠， 脉搏与脉搏重叠， 心率与心率重叠
  if (lappingType && symbolStyle) {
    // 2个相同的点去掉，取合并的点
    // 相同的点分成1组
    const coordinateToPoints = {};
    samePoint.forEach((point) => {
      let { x1, y1 } = point;
      if (!coordinateToPoints[`${x1}_${y1}`]) {
        coordinateToPoints[`${x1}_${y1}`] = [];
      }
      coordinateToPoints[`${x1}_${y1}`].push(point);
    });
    //console.log({ samePoint, coordinateToPoints });
    for (let coordinate in coordinateToPoints) {
      // 排序 ['体温', '脉搏', '心率]
      let sortNo = {
        体温: 0,
        脉搏: 1,
        心率: 2,
      };
      let points = coordinateToPoints[coordinate];
      let totalPoints = [];
      points.forEach((item) => {
        if (item.values) {
          item.values.forEach((value) => {
            value.x1 = item.x1;
            value.y1 = item.y1;
          });
          totalPoints = totalPoints.concat(item.values);
        } else {
          totalPoints.push(item);
        }
      });

      totalPoints.sort((a, b) => {
        return sortNo[a.config.name] - sortNo[b.config.name];
      });
      coordinateToPoints[coordinate] = totalPoints;
    }

    for (let coordinate in coordinateToPoints) {
      let points = coordinateToPoints[coordinate];
      // 起搏器特殊处理
      let nameArray = points.map((item) => {
        if (item.vitalsigns === "脉搏" && item.flag == 1) return "起搏器";
        if (item.vitalsigns === "心率" && item.flag == 1) return "心脏起搏器";
        if (item.vitalsigns.includes("呼吸")) return "呼吸";
        return item.vitalsigns;
      });

      nameArray = Array.from(new Set(nameArray)); // nameArray去重

      let nameJoin = nameArray.join(",");
      if (nameJoin === "心率,脉搏") {
        nameJoin = "脉搏,心率";
      }
      if (nameJoin === "心率,起搏器") {
        nameJoin = "起搏器,心率";
      }

      if (nameJoin === "心脏起搏器,脉搏") {
        nameJoin = "脉搏,心脏起搏器";
      }

      if (nameJoin === "心脏起搏器,脉搏") {
        nameJoin = "脉搏,心脏起搏器";
      }

      let symbolStyle =
        nameToSymbolStyle[nameJoin] ||
        symbolIdToStyle[sameConfig["over-symbol"]];

      if (symbolStyle) {
        let { symbol1, symbol2, color1, color2, fontSize1, fontSize2 } =
          symbolStyle;
        // 详情重叠合并
        if (lappingType == 1) {
          showSamePoint.push({
            ...points[0],
            ...symbolStyle,
            values: points,
            nameJoinSymbol: sameConfig.name,
          });
        }
        // 详情分开点击显示
        if (lappingType == 2) {
          let newPoints = [];
          newPoints[0] = points[1];
          newPoints[1] = points[0];

          newPoints[0].symbol1 = symbol1;
          newPoints[0].color1 = color1;
          newPoints[0].fontSize1 = fontSize1;

          newPoints[1].symbol1 = symbol2;
          newPoints[1].color1 = color2;
          newPoints[1].fontSize1 = fontSize2;

          showSamePoint = showSamePoint.concat(newPoints);
        }
      }
    }
  } else {
    showSamePoint = samePoint;
  }

  return showSamePoint;
};

/**
 * 解析重叠通用
 */
let parseOverLapping = (samePoint, sameConfig, symbolIdToStyle) => {
  if (samePoint.length === 0) return [];

  let showSamePoint = [];
  let overLapping = ["undefined", 2, "2"].includes(sameConfig["over-lapping"])
    ? 2
    : sameConfig["over-lapping"] || 1;

  if (overLapping == 1) {
    // 单独图标显示
    showSamePoint = parseOverLappingSpecial(
      samePoint,
      sameConfig,
      symbolIdToStyle
    );
    //console.log('overLapping', { showSamePoint, samePoint, sameConfig, symbolIdToStyle })
  }
  if (overLapping == 2) {
    // 不做处理
    showSamePoint = samePoint;
  }
  let sortNo;

  if (overLapping == 3) {
    // 体温在上
    sortNo = {
      体温: 2,
      脉搏: 1,
      心率: 1,
    };
  } else if (overLapping == 4) {
    // 体温在下
    sortNo = {
      体温: 1,
      脉搏: 2,
      心率: 2,
    };
  }
  if (sortNo) {
    showSamePoint = samePoint;
    showSamePoint.sort((a, b) => {
      return sortNo[a.config.name] - sortNo[b.config.name];
    });
  }

  return showSamePoint;
};

onMounted(() => {
  let vitalLineOutData = parseVitalLineOut();

  vitalLineOut.value = vitalLineOutData;



  // console.log("vitalLineOut", vitalLineOut.value);

});
</script>

<style lang="scss" scoped></style>
